home *** CD-ROM | disk | FTP | other *** search
- package sun.font;
-
- import java.awt.Rectangle;
- import java.awt.geom.AffineTransform;
- import java.awt.geom.GeneralPath;
- import java.awt.geom.NoninvertibleTransformException;
- import java.awt.geom.Point2D;
- import java.awt.geom.Rectangle2D;
- import java.lang.ref.SoftReference;
- import java.util.HashMap;
- import java.util.concurrent.ConcurrentHashMap;
-
- public class FileFontStrike extends PhysicalStrike {
- static final int INVISIBLE_GLYPHS = 65534;
- private FileFont fileFont;
- private static final int UNINITIALISED = 0;
- private static final int INTARRAY = 1;
- private static final int LONGARRAY = 2;
- private static final int SEGINTARRAY = 3;
- private static final int SEGLONGARRAY = 4;
- private int glyphCacheFormat = 0;
- private static final int SEGSHIFT = 8;
- private static final int SEGSIZE = 256;
- private boolean segmentedCache;
- private int[][] segIntGlyphImages;
- private long[][] segLongGlyphImages;
- protected float[] horizontalAdvances;
- ConcurrentHashMap boundsMap;
- SoftReference glyphMetricsMapRef;
- AffineTransform invertDevTx;
- boolean useNatives;
- NativeStrike[] nativeStrikes;
- private static final int SLOTZEROMAX = 16777215;
-
- FileFontStrike(FileFont var1, FontStrikeDesc var2) {
- super(var1, var2);
- this.fileFont = var1;
- if (var2.style != var1.style) {
- if ((var2.style & 2) == 2 && (var1.style & 2) == 0) {
- this.algoStyle = true;
- this.italic = 0.7F;
- }
-
- if ((var2.style & 1) == 1 && (var1.style & 1) == 0) {
- this.algoStyle = true;
- this.boldness = 1.33F;
- }
- }
-
- double[] var3 = new double[4];
- AffineTransform var4 = var2.glyphTx;
- var4.getMatrix(var3);
- if (!var2.devTx.isIdentity() && var2.devTx.getType() != 1) {
- try {
- this.invertDevTx = var2.devTx.createInverse();
- } catch (NoninvertibleTransformException var11) {
- }
- }
-
- if (!Double.isNaN(var3[0]) && !Double.isNaN(var3[1]) && !Double.isNaN(var3[2]) && !Double.isNaN(var3[3])) {
- this.pScalerContext = this.createScalerContext(var1.getScaler(), var3, var1 instanceof TrueTypeFont, var2.aaHint, var2.fmHint, this.algoStyle, this.boldness, this.italic);
- } else {
- this.pScalerContext = getNullScalerContext(FileFont.getNullScaler());
- }
-
- this.mapper = var1.getMapper();
- int var5 = this.mapper.getNumGlyphs();
- float var6 = (float)var3[3];
- int var7 = (int)var6;
- boolean var8 = (var4.getType() & 124) == 0;
- this.segmentedCache = var5 > 4096 || var5 > 512 && (!var8 || var6 != (float)var7 || var7 < 6 || var7 > 36);
- if (this.pScalerContext == 0L) {
- this.disposer = new FontStrikeDisposer(var1, var2);
- this.initGlyphCache();
- this.pScalerContext = getNullScalerContext(FileFont.getNullScaler());
- FontManager.deRegisterBadFont(var1);
- } else {
- if (var1.checkUseNatives() && var2.aaHint == 0 && !this.algoStyle && var3[1] == (double)0.0F && var3[2] == (double)0.0F && var3[0] >= (double)6.0F && var3[0] <= (double)36.0F && var3[0] == var3[3]) {
- this.useNatives = true;
- int var9 = var1.nativeFonts.length;
- this.nativeStrikes = new NativeStrike[var9];
-
- for(int var10 = 0; var10 < var9; ++var10) {
- this.nativeStrikes[var10] = new NativeStrike(var1.nativeFonts[var10], var2, false);
- }
- }
-
- this.disposer = new FontStrikeDisposer(var1, var2, this.pScalerContext);
- this.getImageWithAdvance = var4.getScaleY() <= (double)48.0F || this.segmentedCache;
- if (!this.getImageWithAdvance && var5 < 1000) {
- this.horizontalAdvances = new float[var5];
-
- for(int var12 = 0; var12 < var5; ++var12) {
- this.horizontalAdvances[var12] = Float.MAX_VALUE;
- }
- }
-
- }
- }
-
- static synchronized native long getNullScalerContext(long var0);
-
- private native long createScalerContext(long var1, double[] var3, boolean var4, int var5, int var6, boolean var7, float var8, float var9);
-
- public int getNumGlyphs() {
- return this.fileFont.getNumGlyphs();
- }
-
- long getGlyphImageFromNative(int var1) {
- char var4 = this.fileFont.glyphToCharMap[var1];
-
- for(int var5 = 0; var5 < this.nativeStrikes.length; ++var5) {
- CharToGlyphMapper var6 = this.fileFont.nativeFonts[var5].getMapper();
- int var7 = var6.charToGlyph(var4) & '\uffff';
- if (var7 != var6.getMissingGlyphCode()) {
- long var2 = this.nativeStrikes[var5].getGlyphImagePtrNoCache(var7);
- if (var2 != 0L) {
- return var2;
- }
- }
- }
-
- return this.fileFont.getGlyphImage(this.pScalerContext, var1);
- }
-
- long getGlyphImagePtr(int var1) {
- if (var1 >= 65534) {
- return StrikeCache.invisibleGlyphPtr;
- } else {
- long var2;
- if ((var2 = this.getCachedGlyphPtr(var1)) != 0L) {
- return var2;
- } else {
- if (this.useNatives) {
- var2 = this.getGlyphImageFromNative(var1);
- } else {
- var2 = this.fileFont.getGlyphImage(this.pScalerContext, var1);
- }
-
- return this.setCachedGlyphPtr(var1, var2);
- }
- }
- }
-
- void getGlyphImagePtrs(int[] var1, long[] var2, int var3) {
- for(int var4 = 0; var4 < var3; ++var4) {
- int var5 = var1[var4];
- if (var5 >= 65534) {
- var2[var4] = StrikeCache.invisibleGlyphPtr;
- } else if ((var2[var4] = this.getCachedGlyphPtr(var5)) == 0L) {
- long var6;
- if (this.useNatives) {
- var6 = this.getGlyphImageFromNative(var5);
- } else {
- var6 = this.fileFont.getGlyphImage(this.pScalerContext, var5);
- }
-
- var2[var4] = this.setCachedGlyphPtr(var5, var6);
- }
- }
-
- }
-
- int getSlot0GlyphImagePtrs(int[] var1, long[] var2, int var3) {
- int var4 = 0;
-
- for(int var5 = 0; var5 < var3; ++var5) {
- int var6 = var1[var5];
- if (var6 >= 16777215) {
- return var4;
- }
-
- ++var4;
- if (var6 >= 65534) {
- var2[var5] = StrikeCache.invisibleGlyphPtr;
- } else if ((var2[var5] = this.getCachedGlyphPtr(var6)) == 0L) {
- long var7;
- if (this.useNatives) {
- var7 = this.getGlyphImageFromNative(var6);
- } else {
- var7 = this.fileFont.getGlyphImage(this.pScalerContext, var6);
- }
-
- var2[var5] = this.setCachedGlyphPtr(var6, var7);
- }
- }
-
- return var4;
- }
-
- long getCachedGlyphPtr(int var1) {
- switch (this.glyphCacheFormat) {
- case 1:
- return (long)this.intGlyphImages[var1] & 4294967295L;
- case 2:
- return this.longGlyphImages[var1];
- case 3:
- int var4 = var1 >> 8;
- if (this.segIntGlyphImages[var4] != null) {
- int var5 = var1 % 256;
- return (long)this.segIntGlyphImages[var4][var5] & 4294967295L;
- }
-
- return 0L;
- case 4:
- int var2 = var1 >> 8;
- if (this.segLongGlyphImages[var2] != null) {
- int var3 = var1 % 256;
- return this.segLongGlyphImages[var2][var3];
- }
-
- return 0L;
- default:
- return 0L;
- }
- }
-
- private synchronized long setCachedGlyphPtr(int var1, long var2) {
- switch (this.glyphCacheFormat) {
- case 1:
- if (this.intGlyphImages[var1] == 0) {
- this.intGlyphImages[var1] = (int)var2;
- return var2;
- }
-
- StrikeCache.freeIntPointer((int)var2);
- return (long)this.intGlyphImages[var1] & 4294967295L;
- case 2:
- if (this.longGlyphImages[var1] == 0L) {
- this.longGlyphImages[var1] = var2;
- return var2;
- }
-
- StrikeCache.freeLongPointer(var2);
- return this.longGlyphImages[var1];
- case 3:
- int var6 = var1 >> 8;
- int var7 = var1 % 256;
- if (this.segIntGlyphImages[var6] == null) {
- this.segIntGlyphImages[var6] = new int[256];
- }
-
- if (this.segIntGlyphImages[var6][var7] == 0) {
- this.segIntGlyphImages[var6][var7] = (int)var2;
- return var2;
- }
-
- StrikeCache.freeIntPointer((int)var2);
- return (long)this.segIntGlyphImages[var6][var7] & 4294967295L;
- case 4:
- int var4 = var1 >> 8;
- int var5 = var1 % 256;
- if (this.segLongGlyphImages[var4] == null) {
- this.segLongGlyphImages[var4] = new long[256];
- }
-
- if (this.segLongGlyphImages[var4][var5] == 0L) {
- this.segLongGlyphImages[var4][var5] = var2;
- return var2;
- }
-
- StrikeCache.freeLongPointer(var2);
- return this.segLongGlyphImages[var4][var5];
- default:
- this.initGlyphCache();
- return this.setCachedGlyphPtr(var1, var2);
- }
- }
-
- private void initGlyphCache() {
- int var1 = this.mapper.getNumGlyphs();
- if (this.segmentedCache) {
- int var2 = (var1 + 256 - 1) / 256;
- if (FontManager.longAddresses) {
- this.glyphCacheFormat = 4;
- this.segLongGlyphImages = new long[var2][];
- this.disposer.segLongGlyphImages = this.segLongGlyphImages;
- } else {
- this.glyphCacheFormat = 3;
- this.segIntGlyphImages = new int[var2][];
- this.disposer.segIntGlyphImages = this.segIntGlyphImages;
- }
- } else if (FontManager.longAddresses) {
- this.glyphCacheFormat = 2;
- this.longGlyphImages = new long[var1];
- this.disposer.longGlyphImages = this.longGlyphImages;
- } else {
- this.glyphCacheFormat = 1;
- this.intGlyphImages = new int[var1];
- this.disposer.intGlyphImages = this.intGlyphImages;
- }
-
- }
-
- float getGlyphAdvance(int var1) {
- if (var1 >= 65534) {
- return 0.0F;
- } else {
- if (this.horizontalAdvances != null) {
- float var2 = this.horizontalAdvances[var1];
- if (var2 != Float.MAX_VALUE) {
- return var2;
- }
- }
-
- float var5;
- if (this.invertDevTx != null) {
- var5 = this.getGlyphMetrics(var1).x;
- } else {
- long var3;
- if (this.getImageWithAdvance) {
- var3 = this.getGlyphImagePtr(var1);
- } else {
- var3 = this.getCachedGlyphPtr(var1);
- }
-
- if (var3 != 0L) {
- var5 = StrikeCache.unsafe.getFloat(var3 + (long)StrikeCache.xAdvanceOffset);
- } else {
- var5 = this.fileFont.getGlyphAdvance(this.pScalerContext, var1);
- }
- }
-
- if (this.horizontalAdvances != null) {
- this.horizontalAdvances[var1] = var5;
- }
-
- return var5;
- }
- }
-
- float getCodePointAdvance(int var1) {
- return this.getGlyphAdvance(this.mapper.charToGlyph(var1));
- }
-
- void getGlyphImageBounds(int var1, Point2D.Float var2, Rectangle var3) {
- long var4 = this.getGlyphImagePtr(var1);
- float var6 = StrikeCache.unsafe.getFloat(var4 + (long)StrikeCache.topLeftXOffset);
- float var7 = StrikeCache.unsafe.getFloat(var4 + (long)StrikeCache.topLeftYOffset);
- var3.x = (int)Math.floor((double)(var2.x + var6));
- var3.y = (int)Math.floor((double)(var2.y + var7));
- var3.width = StrikeCache.unsafe.getShort(var4 + (long)StrikeCache.widthOffset) & '\uffff';
- var3.height = StrikeCache.unsafe.getShort(var4 + (long)StrikeCache.heightOffset) & '\uffff';
- if ((this.desc.aaHint == 4 || this.desc.aaHint == 5) && var6 <= -2.0F) {
- int var8 = this.getGlyphImageMinX(var4, var3.x);
- if (var8 > var3.x) {
- ++var3.x;
- --var3.width;
- }
- }
-
- }
-
- private int getGlyphImageMinX(long var1, int var3) {
- char var4 = StrikeCache.unsafe.getChar(var1 + (long)StrikeCache.widthOffset);
- char var5 = StrikeCache.unsafe.getChar(var1 + (long)StrikeCache.heightOffset);
- char var6 = StrikeCache.unsafe.getChar(var1 + (long)StrikeCache.rowBytesOffset);
- if (var6 == var4) {
- return var3;
- } else {
- long var7;
- if (StrikeCache.nativeAddressSize == 4) {
- var7 = (long)(-1 & StrikeCache.unsafe.getInt(var1 + (long)StrikeCache.pixelDataOffset));
- } else {
- var7 = StrikeCache.unsafe.getLong(var1 + (long)StrikeCache.pixelDataOffset);
- }
-
- if (var7 == 0L) {
- return var3;
- } else {
- for(int var9 = 0; var9 < var5; ++var9) {
- for(int var10 = 0; var10 < 3; ++var10) {
- if (StrikeCache.unsafe.getByte(var7 + (long)(var9 * var6) + (long)var10) != 0) {
- return var3;
- }
- }
- }
-
- return var3 + 1;
- }
- }
- }
-
- StrikeMetrics getFontMetrics() {
- if (this.strikeMetrics == null) {
- this.strikeMetrics = this.fileFont.getFontMetrics(this.pScalerContext);
- if (this.invertDevTx != null) {
- this.strikeMetrics.convertToUserSpace(this.invertDevTx);
- }
- }
-
- return this.strikeMetrics;
- }
-
- Point2D.Float getGlyphMetrics(int var1) {
- Point2D.Float var2 = new Point2D.Float();
- if (var1 >= 65534) {
- return var2;
- } else {
- long var3;
- if (this.getImageWithAdvance) {
- var3 = this.getGlyphImagePtr(var1);
- } else {
- var3 = this.getCachedGlyphPtr(var1);
- }
-
- if (var3 != 0L) {
- var2 = new Point2D.Float();
- var2.x = StrikeCache.unsafe.getFloat(var3 + (long)StrikeCache.xAdvanceOffset);
- var2.y = StrikeCache.unsafe.getFloat(var3 + (long)StrikeCache.yAdvanceOffset);
- if (this.invertDevTx != null) {
- this.invertDevTx.deltaTransform(var2, var2);
- }
- } else {
- Integer var5 = new Integer(var1);
- Point2D.Float var6 = null;
- HashMap var7 = null;
- if (this.glyphMetricsMapRef != null) {
- var7 = (HashMap)this.glyphMetricsMapRef.get();
- }
-
- if (var7 != null) {
- synchronized(this) {
- var6 = (Point2D.Float)var7.get(var5);
- if (var6 != null) {
- var2.x = var6.x;
- var2.y = var6.y;
- return var2;
- }
- }
- }
-
- if (var6 == null) {
- this.fileFont.getGlyphMetrics(this.pScalerContext, var1, var2);
- if (this.invertDevTx != null) {
- this.invertDevTx.deltaTransform(var2, var2);
- }
-
- var6 = new Point2D.Float(var2.x, var2.y);
- synchronized(this) {
- if (var7 == null) {
- var7 = new HashMap();
- this.glyphMetricsMapRef = new SoftReference(var7);
- }
-
- var7.put(var5, var6);
- }
- }
- }
-
- return var2;
- }
- }
-
- Point2D.Float getCharMetrics(char var1) {
- return this.getGlyphMetrics(this.mapper.charToGlyph(var1));
- }
-
- Rectangle2D.Float getGlyphOutlineBounds(int var1) {
- if (this.boundsMap == null) {
- this.boundsMap = new ConcurrentHashMap();
- }
-
- Integer var2 = new Integer(var1);
- Rectangle2D.Float var3 = (Rectangle2D.Float)this.boundsMap.get(var2);
- if (var3 == null) {
- var3 = this.fileFont.getGlyphOutlineBounds(this.pScalerContext, var1);
- this.boundsMap.put(var2, var3);
- }
-
- return var3;
- }
-
- public Rectangle2D getOutlineBounds(int var1) {
- return this.fileFont.getGlyphOutlineBounds(this.pScalerContext, var1);
- }
-
- GeneralPath getGlyphOutline(int var1, float var2, float var3) {
- return this.fileFont.getGlyphOutline(this.pScalerContext, var1, var2, var3);
- }
-
- GeneralPath getGlyphVectorOutline(int[] var1, float var2, float var3) {
- return this.fileFont.getGlyphVectorOutline(this.pScalerContext, var1, var1.length, var2, var3);
- }
-
- protected void adjustPoint(Point2D.Float var1) {
- if (this.invertDevTx != null) {
- this.invertDevTx.deltaTransform(var1, var1);
- }
-
- }
- }
-